﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ModelViewer
{
    /// <summary>
    /// A view is a part of the ModelViewerControl window that we draw in. Views allow
    /// us to have more than one simultaneous view.
    /// </summary>
    public class View
    {
        #region Fields

        private Camera camera = new Camera();

        private Viewport viewport = new Viewport();



        #endregion

        #region Properties

        /// <summary>
        /// The camera associated with the view
        /// </summary>
        public Camera Camera
        {
            get { return camera; }
        }

        /// <summary>
        /// The viewport for this view
        /// </summary>
        public Viewport Viewport
        {
            get { return viewport; }
            set { viewport = value; }
        }
        
        #endregion


        #region Constructor

        public View()
        {
            camera.AutoDepth = true;
            camera.Center = Vector3.Zero;
            camera.Eye = new Vector3(1, 1, 1) * 100;
            camera.ZNear = camera.CameraDistance - 200;
            camera.ZFar = camera.CameraDistance + 1000;
            camera.Fov = MathHelper.ToRadians(20);

            viewport.MinDepth = 0.0f;
            viewport.MaxDepth = 1.0f;
        }

        #endregion

        /// <summary>
        /// Set the size of the viewport
        /// </summary>
        /// <param name="location"></param>
        /// <param name="size"></param>
        public void SetViewport(System.Drawing.Point location, System.Drawing.Size size)
        {
            viewport.X = location.X;
            viewport.Y = location.Y;
            viewport.Width = size.Width;
            viewport.Height = size.Height;
            camera.Aspect = viewport.AspectRatio;
        }

        /// <summary>
        /// Test to see if a point in in a view
        /// </summary>
        /// <param name="location"></param>
        /// <returns></returns>
        public bool InView(System.Drawing.Point location)
        {
            return (location.X >= viewport.X && location.X < (viewport.X + viewport.Width) &&
                location.Y >= viewport.Y && location.Y < (viewport.Y + viewport.Height));
        }


        /// <summary>
        /// Move the camera target left/right and up/down based on mouse movements
        /// </summary>
        public void Translate(int fmX, int fmY, int toX, int toY)
        {
            // Project the center to the screen to determine the depth
            Vector3 centerScreen = viewport.Project(camera.Center, camera.Projection, camera.View, Matrix.Identity);

            // Determine the point at that depth we have hit with the mouse before
            Vector3 oldPoint = viewport.Unproject(new Vector3(fmX, fmY, centerScreen.Z), camera.Projection, camera.View, Matrix.Identity);

            //  Determine the new point we have hit at that depth
            Vector3 newPoint = viewport.Unproject(new Vector3(toX, toY, centerScreen.Z), camera.Projection, camera.View, Matrix.Identity);

            // Offset the camera center
            camera.Center = camera.Center + (oldPoint - newPoint);
        }

    }
}
